package com.swingson.properties;

import com.swingson.SwingsonGui;
import com.swingson.exceptions.SwingsonException;
import com.swingson.interpreter.Parser;
import com.swingson.interpreter.ast.base.BaseAst;
import com.swingson.jsonparser.JsonElement;
import com.swingson.layout.swingsonlayout.SwingsonLayout;
import com.swingson.properties.impl.PropertyProcessors;
import java.awt.Container;
import javax.swing.JComponent;

/**
 * @author sad
 */
public abstract class AnchoredPropertyProcessor extends PropertyProcessors.PrimitivePropertyProcessor {

    private Anchor parseAnchor(String anch) {
        String[] strs = anch.split(":");
        try {
            Anchor findedAnch = Anchor.valueOf(strs[1]);
            return findedAnch;
        } catch (Exception ex) {
            throw new SwingsonException("Cannot parse anchor '" + anch + "'");
        }
    }

    public PositionWithAnchor parsePosWithAnchor(String value, JsonElement jsonElement, JComponent component, SwingsonGui gui, String propertyName, Parser.CalculationOrientation orientation) {
        String[] values = value.split(",");
        if (values.length == 1) {
            Parser parser = new Parser();
            BaseAst ast = parser.parseString(component, component, gui, values[0], Parser.CalculationOrientation.horizontal);
            return new PositionWithAnchor(Anchor.TL, Anchor.TL, ast);
        }

        if (values.length == 2) {
            PositionWithAnchor anchor = new PositionWithAnchor(null, null, null);
            if (values[0].startsWith("pa:")) {
                Anchor a=parseAnchor(values[0]);
                anchor.setParent(a);
            } else if (values[0].startsWith("ca:")) {
                Anchor a=parseAnchor(values[0]);
                anchor.setCurrent(a);
            } else {
                throw new SwingsonException("Cannot parse anchor '" + values[0] + "' as anchor. [" + value + "]");
            }

            Parser parser = new Parser();
            BaseAst ast = parser.parseString(component, component, gui, values[1], Parser.CalculationOrientation.horizontal);
            return new PositionWithAnchor(Anchor.TL, Anchor.TL, ast);
        }
        if (values.length == 3) {
            PositionWithAnchor anchor = new PositionWithAnchor(null, null, null);
            if (values[0].startsWith("pa:")) {
                Anchor a=parseAnchor(values[0]);
                anchor.setParent(a);
            }else{
                throw new SwingsonException("["+value+"] first should be parent anchor - pa:...");
            }

            if (values[1].startsWith("ca:")) {
                Anchor a=parseAnchor(values[0]);
                anchor.setCurrent(a);
            } else {
                throw new SwingsonException("["+value+"] second should be current component anchor - ca:...");
            }

            Parser parser = new Parser();
            BaseAst ast = parser.parseString(component, component, gui, values[2], Parser.CalculationOrientation.horizontal);
            anchor.setAst(ast);
            return anchor;
        }

        throw new SwingsonException("Cannot parse position property ["+value+"]");
    }

    public class PositionWithAnchor {

        private Anchor parent;
        private Anchor current;
        private BaseAst ast;

        public PositionWithAnchor(Anchor parent, Anchor current, BaseAst ast) {
            this.parent = parent;
            this.current = current;
            this.ast = ast;
        }

        public PositionWithAnchor() {
        }

        public void setParent(Anchor parent) {
            this.parent = parent;
        }

        public void setCurrent(Anchor current) {
            this.current = current;
        }

        public void setAst(BaseAst ast) {
            this.ast = ast;
        }

        public Anchor getParent() {
            return parent;
        }

        public Anchor getCurrent() {
            return current;
        }

        public BaseAst getAst() {
            return ast;
        }

    }
    
    protected boolean isSwingsonLayout(Container c){
        return c.getLayout() != null && c.getLayout().getClass() == SwingsonLayout.class;
    }
}
